home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / ptv1n6.arc / L2.ASM < prev    next >
Assembly Source File  |  1991-01-21  |  4KB  |  97 lines

  1. ; Searches a text buffer for a text string. Uses REPNZ SCASB to scan
  2. ; the buffer for locations that match a specified character of the
  3. ; searched-for string, then uses REPZ CMPS to check fully only those
  4. ; locations that REPNZ SCASB has identified as potential matches.
  5. ;
  6. ; C small model-callable as:
  7. ;    unsigned char * FindString(unsigned char * Buffer,
  8. ;        unsigned int BufferLength, unsigned char * SearchString,
  9. ;    unsigned int SearchStringLength,
  10. ;    unsigned int ScanCharOffset);
  11. ;
  12. ; Returns a pointer to the first match for SearchString in Buffer, or
  13. ; a NULL pointer if no match is found. Buffer should not start at
  14. ; offset 0 in the data segment to avoid confusing a match at 0 with
  15. ; no match found.
  16.  
  17. Parms    struc
  18.         dw    2 dup(?) ;pushed BP/return address
  19. Buffer        dw    ?    ;pointer to buffer to search
  20. BufferLength    dw    ?    ;length of buffer to search
  21. SearchString    dw    ?    ;pointer to string for which to search
  22. SearchStringLength dw    ?    ;length of string for which to search
  23. ScanCharOffset    dw    ?    ;offset in string of character for
  24.                 ; which to scan
  25. Parms    ends
  26.     .model    small
  27.     .code
  28.     public _FindString
  29. _FindString    proc    near
  30.     push    bp    ;preserve caller's stack frame
  31.     mov    bp,sp    ;point to our stack frame
  32.     push    si    ;preserve caller's register variables
  33.     push    di
  34.     cld        ;make string instructions increment pointers
  35.     mov    si,[bp+SearchString] ;pointer to string to search for
  36.     mov    cx,[bp+SearchStringLength] ;length of string
  37.     jcxz    FindStringNotFound ;no match if string is 0 length
  38.     mov    dx,[bp+BufferLength] ;length of buffer
  39.     sub    dx,cx    ;difference between buffer and search lengths
  40.     jc    FindStringNotFound ;no match if search string is
  41.             ; longer than buffer
  42.     inc    dx    ;difference between buffer and search string
  43.             ; lengths, plus 1 (# of possible string start
  44.             ; locations to check in the buffer)
  45.     mov    di,ds
  46.     mov    es,di
  47.     mov    di,[bp+Buffer]    ;point ES:DI to buffer to search thru
  48.     mov    bx,[bp+ScanCharOffset] ;offset in string of character
  49.             ; on which to scan
  50.     add    di,bx    ;point ES:DI to first buffer byte to scan
  51.     mov    al,[si+bx] ;put the scan character in AL
  52.     inc    bx    ;set BX to the offset back to the start of the
  53.             ; potential full match after a scan match,
  54.             ; accounting for the 1-byte overrun of
  55.             ; REPNZ SCASB
  56. FindStringLoop:
  57.     mov    cx,dx    ;put remaining buffer search length in CX
  58.     repnz    scasb    ;scan for the scan byte
  59.     jnz    FindStringNotFound ;not found, so there's no match
  60.             ;found, so we have a potential match-check the
  61.             ; rest of this candidate location
  62.     push    di    ;remember the address of the next byte to scan
  63.     mov    dx,cx    ;set aside the remaining length to search in
  64.             ; the buffer
  65.     sub    di,bx    ;point back to the potential start of the
  66.             ; match in the buffer
  67.     mov    si,[bp+SearchString] ;point to the start of the string
  68.     mov    cx,[bp+SearchStringLength] ;string length
  69.     shr    cx,1    ;convert to word for faster search
  70.     jnc    FindStringWord ;do word search if no odd byte
  71.     cmpsb        ;compare the odd byte
  72.     jnz    FindStringNoMatch ;odd byte doesn't match, so we
  73.             ; haven't found the search string here
  74. FindStringWord:
  75.     jcxz    FindStringFound ;if the string is only 1 byte long,
  76.             ; we've found a match
  77.     repz    cmpsw    ;check the rest of the string a word at a time
  78.     jz    FindStringFound ;it's a match
  79. FindStringNoMatch:
  80.     pop    di    ;get back pointer to the next byte to scan
  81.     and    dx,dx    ;is there anything left to check?
  82.     jnz    FindStringLoop ;yes-check next byte
  83. FindStringNotFound:
  84.     sub    ax,ax    ;return a NULL pointer indicating that the
  85.     jmp    FindStringDone ; string was not found
  86. FindStringFound:
  87.     pop    ax    ;point to the buffer location at which the
  88.     sub    ax,bx    ; string was found (earlier we pushed the
  89.             ; address of the byte after the scan match)
  90. FindStringDone:
  91.     pop    di    ;restore caller's register variables
  92.     pop    si
  93.     pop    bp    ;restore caller's stack frame
  94.     ret
  95. _FindString    endp
  96.     end
  97.